// SPDX-FileCopyrightText: Copyright 2025-2025 深圳市同心圆网络有限公司
// SPDX-License-Identifier: Apache-2.0

package roadmap_rag_api_serv

import (
	"context"
	"time"

	"gitcode.com/lvupclub/lvup-api/dao"
	"gitcode.com/lvupclub/lvup-api/dao/roadmap_dao"
	"gitcode.com/lvupclub/lvup-api/dao/user_dao"
	"gitcode.com/lvupclub/proto-gen-go.git/src/roadmap_rag_api"
	"gitcode.com/lvupclub/proto-gen-go.git/src/user_api"
	"github.com/google/uuid"
)

func (apiImpl *RoadmapRagApiImpl) AddConfig(ctx context.Context, req *roadmap_rag_api.AddConfigRequest) (*roadmap_rag_api.AddConfigResponse, error) {
	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &roadmap_rag_api.AddConfigResponse{
			Code:   roadmap_rag_api.AddConfigResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	userItem, err := user_dao.UserInfoDao.GetById(ctx, sessItem.UserId)
	if err != nil {
		return nil, err
	}
	//只有教练可以创建路线图RAG配置
	if userItem.BasicInfo.UserRole != user_api.USER_ROLE_USER_ROLE_COACH {
		return &roadmap_rag_api.AddConfigResponse{
			Code:   roadmap_rag_api.AddConfigResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}
	roadmapItem, err := roadmap_dao.RoadmapInfoDao.Get(ctx, req.RoadmapId)
	if err != nil {
		return &roadmap_rag_api.AddConfigResponse{
			Code:   roadmap_rag_api.AddConfigResponse_CODE_NO_ROADMAP,
			ErrMsg: "成长路线不存在",
		}, nil
	}
	//只有路线图owner可以
	if roadmapItem.OwnerUserId != sessItem.UserId {
		return &roadmap_rag_api.AddConfigResponse{
			Code:   roadmap_rag_api.AddConfigResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	ragConfigId := uuid.NewString()
	nowTime := time.Now().UnixMilli()

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx context.Context) (interface{}, error) {
		err = roadmap_dao.RagConfigDao.Insert(sessCtx, &roadmap_dao.RagConfigDbItem{
			RagConfigId: ragConfigId,
			RoadmapId:   req.RoadmapId,
			BasicConfig: roadmap_dao.BasicRagConfigDbItem{
				Name:         req.BasicConfig.Name,
				ProviderType: req.BasicConfig.ProviderType,
				BaseApiAddr:  req.BasicConfig.BaseApiAddr,
				ApiKey:       req.BasicConfig.ApiKey,
				AgentId:      req.BasicConfig.AgentId,
			},
			CreateTime: nowTime,
			UpdateTime: nowTime,
		})
		if err != nil {
			return nil, err
		}
		return &roadmap_rag_api.AddConfigResponse{
			Code:        roadmap_rag_api.AddConfigResponse_CODE_OK,
			RagConfigId: ragConfigId,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*roadmap_rag_api.AddConfigResponse), nil
}

func (apiImpl *RoadmapRagApiImpl) UpdateConfig(ctx context.Context, req *roadmap_rag_api.UpdateConfigRequest) (*roadmap_rag_api.UpdateConfigResponse, error) {
	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &roadmap_rag_api.UpdateConfigResponse{
			Code:   roadmap_rag_api.UpdateConfigResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	userItem, err := user_dao.UserInfoDao.GetById(ctx, sessItem.UserId)
	if err != nil {
		return nil, err
	}
	//只有教练可以更新路线图RAG配置
	if userItem.BasicInfo.UserRole != user_api.USER_ROLE_USER_ROLE_COACH {
		return &roadmap_rag_api.UpdateConfigResponse{
			Code:   roadmap_rag_api.UpdateConfigResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}
	roadmapItem, err := roadmap_dao.RoadmapInfoDao.Get(ctx, req.RoadmapId)
	if err != nil {
		return &roadmap_rag_api.UpdateConfigResponse{
			Code:   roadmap_rag_api.UpdateConfigResponse_CODE_NO_ROADMAP,
			ErrMsg: "成长路线不存在",
		}, nil
	}
	//只有路线图owner可以
	if roadmapItem.OwnerUserId != sessItem.UserId {
		return &roadmap_rag_api.UpdateConfigResponse{
			Code:   roadmap_rag_api.UpdateConfigResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	//检查配置是否存在
	exist, err := roadmap_dao.RagConfigDao.Exist(ctx, req.RoadmapId, req.RagConfigId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &roadmap_rag_api.UpdateConfigResponse{
			Code:   roadmap_rag_api.UpdateConfigResponse_CODE_NO_CONFIG,
			ErrMsg: "知识库配置不存在",
		}, nil
	}

	nowTime := time.Now().UnixMilli()

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx context.Context) (interface{}, error) {
		err = roadmap_dao.RagConfigDao.UpdateBasic(sessCtx, req.RoadmapId, req.RagConfigId, &roadmap_dao.BasicRagConfigDbItem{
			Name:         req.BasicConfig.Name,
			ProviderType: req.BasicConfig.ProviderType,
			BaseApiAddr:  req.BasicConfig.BaseApiAddr,
			ApiKey:       req.BasicConfig.ApiKey,
			AgentId:      req.BasicConfig.AgentId,
		}, nowTime)
		if err != nil {
			return nil, err
		}
		return &roadmap_rag_api.UpdateConfigResponse{
			Code: roadmap_rag_api.UpdateConfigResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*roadmap_rag_api.UpdateConfigResponse), nil
}

func (apiImpl *RoadmapRagApiImpl) RemoveConfig(ctx context.Context, req *roadmap_rag_api.RemoveConfigRequest) (*roadmap_rag_api.RemoveConfigResponse, error) {
	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &roadmap_rag_api.RemoveConfigResponse{
			Code:   roadmap_rag_api.RemoveConfigResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	userItem, err := user_dao.UserInfoDao.GetById(ctx, sessItem.UserId)
	if err != nil {
		return nil, err
	}
	//只有教练可以删除路线图RAG配置
	if userItem.BasicInfo.UserRole != user_api.USER_ROLE_USER_ROLE_COACH {
		return &roadmap_rag_api.RemoveConfigResponse{
			Code:   roadmap_rag_api.RemoveConfigResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}
	roadmapItem, err := roadmap_dao.RoadmapInfoDao.Get(ctx, req.RoadmapId)
	if err != nil {
		return &roadmap_rag_api.RemoveConfigResponse{
			Code:   roadmap_rag_api.RemoveConfigResponse_CODE_NO_ROADMAP,
			ErrMsg: "成长路线不存在",
		}, nil
	}
	//只有路线图owner可以
	if roadmapItem.OwnerUserId != sessItem.UserId {
		return &roadmap_rag_api.RemoveConfigResponse{
			Code:   roadmap_rag_api.RemoveConfigResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}
	//检查配置是否存在
	exist, err := roadmap_dao.RagConfigDao.Exist(ctx, req.RoadmapId, req.RagConfigId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &roadmap_rag_api.RemoveConfigResponse{
			Code: roadmap_rag_api.RemoveConfigResponse_CODE_OK,
		}, nil
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx context.Context) (interface{}, error) {
		err = roadmap_dao.RagConfigDao.Remove(sessCtx, req.RoadmapId, req.RagConfigId)
		if err != nil {
			return nil, err
		}
		return &roadmap_rag_api.RemoveConfigResponse{
			Code: roadmap_rag_api.RemoveConfigResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*roadmap_rag_api.RemoveConfigResponse), nil
}

func (apiImpl *RoadmapRagApiImpl) ListConfig(ctx context.Context, req *roadmap_rag_api.ListConfigRequest) (*roadmap_rag_api.ListConfigResponse, error) {
	emptyList := []*roadmap_rag_api.RagConfig{}

	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &roadmap_rag_api.ListConfigResponse{
			Code:       roadmap_rag_api.ListConfigResponse_CODE_WRONG_SESSION,
			ErrMsg:     "会话不存在",
			ConfigList: emptyList,
		}, nil
	}
	userItem, err := user_dao.UserInfoDao.GetById(ctx, sessItem.UserId)
	if err != nil {
		return nil, err
	}
	//只有教练可以列出路线图RAG配置
	if userItem.BasicInfo.UserRole != user_api.USER_ROLE_USER_ROLE_COACH {
		return &roadmap_rag_api.ListConfigResponse{
			Code:       roadmap_rag_api.ListConfigResponse_CODE_NO_PERMISSION,
			ErrMsg:     "没有权限",
			ConfigList: emptyList,
		}, nil
	}
	roadmapItem, err := roadmap_dao.RoadmapInfoDao.Get(ctx, req.RoadmapId)
	if err != nil {
		return &roadmap_rag_api.ListConfigResponse{
			Code:       roadmap_rag_api.ListConfigResponse_CODE_NO_ROADMAP,
			ErrMsg:     "成长路线不存在",
			ConfigList: emptyList,
		}, nil
	}
	//只有路线图owner可以
	if roadmapItem.OwnerUserId != sessItem.UserId {
		return &roadmap_rag_api.ListConfigResponse{
			Code:       roadmap_rag_api.ListConfigResponse_CODE_NO_PERMISSION,
			ErrMsg:     "没有权限",
			ConfigList: emptyList,
		}, nil
	}

	configItemList, err := roadmap_dao.RagConfigDao.List(ctx, req.RoadmapId)
	if err != nil {
		return nil, err
	}

	configList := []*roadmap_rag_api.RagConfig{}
	for _, configItem := range configItemList {
		config := configItem.ToRagConfig()
		configList = append(configList, config)
	}

	return &roadmap_rag_api.ListConfigResponse{
		Code:       roadmap_rag_api.ListConfigResponse_CODE_OK,
		ConfigList: configList,
	}, nil
}

func (apiImpl *RoadmapRagApiImpl) GetConfig(ctx context.Context, req *roadmap_rag_api.GetConfigRequest) (*roadmap_rag_api.GetConfigResponse, error) {
	emptyInfo := &roadmap_rag_api.RagConfig{
		BasicConfig: &roadmap_rag_api.BasicRagConfig{},
	}

	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &roadmap_rag_api.GetConfigResponse{
			Code:   roadmap_rag_api.GetConfigResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
			Config: emptyInfo,
		}, nil
	}
	userItem, err := user_dao.UserInfoDao.GetById(ctx, sessItem.UserId)
	if err != nil {
		return nil, err
	}
	//只有教练可以列出路线图RAG配置
	if userItem.BasicInfo.UserRole != user_api.USER_ROLE_USER_ROLE_COACH {
		return &roadmap_rag_api.GetConfigResponse{
			Code:   roadmap_rag_api.GetConfigResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
			Config: emptyInfo,
		}, nil
	}
	roadmapItem, err := roadmap_dao.RoadmapInfoDao.Get(ctx, req.RoadmapId)
	if err != nil {
		return &roadmap_rag_api.GetConfigResponse{
			Code:   roadmap_rag_api.GetConfigResponse_CODE_NO_ROADMAP,
			ErrMsg: "成长路线不存在",
			Config: emptyInfo,
		}, nil
	}
	//只有路线图owner可以
	if roadmapItem.OwnerUserId != sessItem.UserId {
		return &roadmap_rag_api.GetConfigResponse{
			Code:   roadmap_rag_api.GetConfigResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
			Config: emptyInfo,
		}, nil
	}

	configItem, err := roadmap_dao.RagConfigDao.Get(ctx, req.RoadmapId, req.RagConfigId)
	if err != nil {
		return &roadmap_rag_api.GetConfigResponse{
			Code:   roadmap_rag_api.GetConfigResponse_CODE_NO_CONFIG,
			ErrMsg: "知识库配置不存在",
			Config: emptyInfo,
		}, nil
	}
	return &roadmap_rag_api.GetConfigResponse{
		Code:   roadmap_rag_api.GetConfigResponse_CODE_OK,
		Config: configItem.ToRagConfig(),
	}, nil
}
